package com.neosavvy.grid{
    import com.neosavvy.grid.event.PickFilterGridEvent;
    import com.neosavvy.grid.renderer.CenteredCheckBoxItemRenderer;
    import com.neosavvy.grid.renderer.CenteredRadioButtonItemRenderer;

    import mx.collections.ArrayCollection;
    import mx.core.ClassFactory;

    public class PickFilterGrid extends AutoFilteringGrid {

        private var bPreSelectedIndicesChanged:Boolean = false;
        private var _preSelectedIndices:ArrayCollection;

        private var bAllowMultipleSelectionChanged:Boolean = false;


        override protected function commitProperties():void {

            addEventListener(PickFilterGridEvent.ITEM_SELECTED, handleItemSelected);

            if (bPreSelectedIndicesChanged)
            {
                var rowsToMarkSelected:ArrayCollection = new ArrayCollection();
                for each (var idx:Number in _preSelectedIndices)
                {
                    var pickFilterRow:PickFilterRow = new ArrayCollection(this.dataProvider.source).getItemAt(idx) as PickFilterRow;
                    if (pickFilterRow)
                        rowsToMarkSelected.addItem(pickFilterRow);
                }


                for each (var row:PickFilterRow in rowsToMarkSelected)
                {
                    row.selected = true;
                    if (allowMultipleSelection)
                        updateMultipleSelectionPickFilterRow(row);
                    else
                        updateSingleSelectionPickFilterRow(row);
                }

                invalidateProperties();
                bPreSelectedIndicesChanged = false;
            }

            if (bAllowMultipleSelectionChanged)
            {
                trace("Executing multiple selection changed");
                if( columns && columns.length >= 1 && columns[0].dataField == "selected")
                {
                    super.invalidateColumns();
                    columns = columns.slice(1,columns.length);
                    bAllowMultipleSelectionChanged = false;
                }

            }


            super.commitProperties();
        }


        /**
         * This value is used to help the selection checkbox column
         * know which value to retrieve from the proxied data set.
         *
         * By default selected is added to the data set, but if there
         * is some other value coming back from the database it can be
         * used instead
         */
        private var _selectedColumnDatafield:String = "selected";

        /**
         * If the default of "Sel" is not what the user wants to display
         * to the users one can override this property
         */
        private var _selectedColumnHeaderText:String = "Sel";

        public function PickFilterGrid() {
            super();
        }

        override public function set dataProvider(value:Object):void {
            var arrayCollection:ArrayCollection = new ArrayCollection();
            for each (var obj:Object in value) {
                arrayCollection.addItem(new PickFilterRow(false, obj))
            }
            super.dataProvider = arrayCollection;
        }

        /***
         *
         * This method will always add the select column with
         * a CenteredCheckBoxItemRenderer to the front of the columns
         * array
         *
         * <grid:AutoFilteringGridColumn
         *    enabledByDefault="true"
         *    autoFilterEnabled="false"
         *    dataField="selected"
         *    headerText="Sel"
         *    itemRenderer="com.neosavvy.grid.renderer.CenteredCheckBoxItemRenderer"
         *    removable="false"/>
         * @param value
         */
        override public function set columns(value:Array):void {

            trace("Setting columns...");

            var selectColumn:AutoFilteringGridColumn = new AutoFilteringGridColumn();
            selectColumn.enabledByDefault = true;
            selectColumn.autoFilterEnabled = false;
            selectColumn.dataField = _selectedColumnDatafield;
            selectColumn.headerText = _selectedColumnHeaderText;

            if (allowMultipleSelection)
                selectColumn.itemRenderer = new ClassFactory(CenteredCheckBoxItemRenderer);
            else
                selectColumn.itemRenderer = new ClassFactory(CenteredRadioButtonItemRenderer);

            selectColumn.removable = false;
            selectColumn.sortable = false;

            value.splice(0, 0, selectColumn);

            super.columns = value;
            invalidateDisplayList();

        }


        override public function set allowMultipleSelection(value:Boolean):void {
            trace("Setting allow multiple to : " + value);
            super.allowMultipleSelection = value;
            bAllowMultipleSelectionChanged = true;
            invalidateProperties();
        }

        override public function searchWrappedFilterFunction(item:Object):Boolean {

            var isItemSelected:Boolean = false;
            if (item.hasOwnProperty(_selectedColumnDatafield)) {
                isItemSelected = item[_selectedColumnDatafield] as Boolean;
            }

            if (super.searchTextControl != null)
                return super.searchWrappedFilterFunction(item) || isItemSelected;
            else
                return super.filterFunction(item) || isItemSelected;

        }

        protected function getSecondarySortColumnName():String {

            var columns:Array = this.columns;
            for each (var column:AutoFilteringGridColumn in columns) {
                if (column.dataField == _selectedColumnDatafield) {
                    continue;
                }
                else {
                    return column.dataField;
                }
            }
            return "";
        }

        private var _selectedNonProxiedItems:ArrayCollection = new ArrayCollection();


        public function get selectedNonProxiedItems():ArrayCollection {
            return _selectedNonProxiedItems;
        }

        public function set selectedNonProxiedItems(value:ArrayCollection):void {
            _selectedNonProxiedItems = value;
        }

        private function updateMultipleSelectionPickFilterRow(pickFilterRow:PickFilterRow):void {
            if (pickFilterRow.selected)
            {
                _selectedNonProxiedItems.addItem(pickFilterRow.wrappedObject);
            }
            else
            {
                var index:int = _selectedNonProxiedItems.getItemIndex(pickFilterRow.wrappedObject);
                _selectedNonProxiedItems.removeItemAt(index);
            }
        }

        private function updateSingleSelectionPickFilterRow(pickFilterRow:PickFilterRow):void {
            _selectedNonProxiedItems.removeAll();
            _selectedNonProxiedItems.addItem(pickFilterRow);
            selectedItem = pickFilterRow;
        }

        protected function handleItemSelected(event:PickFilterGridEvent):void {

            var pickFilterRow:PickFilterRow = event.pickFilterRow;

            if (allowMultipleSelection)
                updateMultipleSelectionPickFilterRow(pickFilterRow);
            else
                updateSingleSelectionPickFilterRow(pickFilterRow);

        }


        [Inspectable(environment="none")]
        [Bindable("valueCommit")]
        [Bindable("change")]
        override public function get selectedItem():Object {
            return (super.selectedItem as PickFilterRow).wrappedObject;
        }

        public function get selectedColumnDatafield():String {
            return _selectedColumnDatafield;
        }

        public function set selectedColumnDatafield(value:String):void {
            _selectedColumnDatafield = value;
        }

        public function get selectedColumnHeaderText():String {
            return _selectedColumnHeaderText;
        }

        public function set selectedColumnHeaderText(value:String):void {
            _selectedColumnHeaderText = value;
        }

        public function get preSelectedIndices():ArrayCollection {
            return _preSelectedIndices;
        }

        public function set preSelectedIndices(value:ArrayCollection):void {
            _preSelectedIndices = value;
            bPreSelectedIndicesChanged = true;
            invalidateProperties();
        }
    }
}
